#include <stdlib.h>
#include <stdio.h>
#include "debug.h"
#include "stralloc.h"
#include "program.h"

int total_num_prog_blocks, total_prog_block_size;

void reference_prog(program_t *progp, char *from)
{
	progp->ref++;
	debug(d_flag, ("reference_prog: /%s ref %d (%s)\n",
				progp->name, progp->ref, from));
}

void deallocate_program(program_t *progp)
{
	int i;

	debug(d_flag, ("free_prog: /%s\n", progp->name));

	total_prog_block_size -= progp->total_size;
	total_num_prog_blocks -= 1;

	/* Free all function names. */
	for (i = 0; i < (int) progp->num_functions_defined; i++)
		if (progp->function_table[i].name)
			free_string(progp->function_table[i].name);
	/* Free all strings */
	for (i = 0; i < (int) progp->num_strings; i++)
		free_string(progp->strings[i]);
	/* Free all variable names */
	for (i = 0; i < (int) progp->num_variables_defined; i++)
		free_string(progp->variable_table[i]);
	free_string(progp->name);

	/*
	 * We're going away for good, not just being swapped, so free up
	 * line_number stuff.
	 */
	/* TODO:
	   if (progp->line_swap_index != -1)
	   remove_line_swap(progp);
	 */
	if (progp->file_info)
		free(progp->file_info);

	free((char *) progp);
}

/*
 * Decrement reference count for a program. If it is 0, then free the prgram.
 * The flag free_sub_strings tells if the propgram plus all used strings
 * should be freed. They normally are, except when objects are swapped,
 * as we want to be able to read the program in again from the swap area.
 * That means that strings are not swapped.
 */
void free_prog(program_t *progp, int free_sub_strings)
{
	progp->ref--;
	if (progp->ref > 0)
		return;
	if (progp->func_ref > 0)
		return;

	if (free_sub_strings)
		deallocate_program(progp);
	else {
		total_prog_block_size -= progp->total_size;
		total_num_prog_blocks -= 1;
		free((char *) progp);
	}
}
